package com.billion.netty.channel;

import com.billion.common.utils.HexUtils;
import com.billion.netty.listener.NettyListener;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelId;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * ChannelSupervise 实体类，用于储存客户端channel连接信息
 */
@Slf4j
@Component
@SuppressWarnings("unchecked")
public class NettyChannel {
    // channel连接组
    private static ChannelGroup GlobalGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    //定义channelid 的map信息
    private static ConcurrentMap<String, ChannelId> ChannelMap = new ConcurrentHashMap();


    /**
     * 保存channel信息
     * @param channel
     */
    public void addChannel(Channel channel){
        GlobalGroup.add(channel);
        ChannelMap.put(channel.id().asLongText(), channel.id());
    }

    /**
     * 移除channel信息
     * @param channel
     */
    public void removeChannel(Channel channel){
        GlobalGroup.remove(channel);
        ChannelMap.remove(channel.id().asLongText());
    }

    /**
     * 公用回写数据到客户端的方法
     * @param receiveStr 需要回写的字符串
     * @param id 通道id信息
     * @param mark 用于打印/log的输出
     * <br>在netty里，进出的都是ByteBuf，楼主应确定服务端是否有对应的编码器，将字符串转化为ByteBuf
     */
    public void writeToClient(String id, String receiveStr, String mark) {
        ChannelId channelId = ChannelMap.get(id);
        if(receiveStr.contains(" ")){
            receiveStr.replace(" ", "");
        }
        Channel channel = GlobalGroup.find(channelId);
        ByteBuf bufff = Unpooled.buffer();//netty需要用ByteBuf传输
        bufff.writeBytes(HexUtils.hexString2Bytes(receiveStr));//对接需要16进制
        //如果通道处于活动状态并且已连接
        if (channel != null && channel.isActive()) {
            channel.writeAndFlush(bufff).addListener(new NettyListener(receiveStr, mark));
        }
    }
}
